package org.gongliang.jsmile.gen;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.gongliang.jsmile.gen.db.DBUtils;
import org.gongliang.jsmile.gen.gentable.GenTables;
import org.gongliang.jsmile.gen.gentable.Table;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class GenKit {


	public static Configuration cfg = null;

	public static void main(String[] args) {
		try {
			autoGen();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 自动生成代码
	 */
	public static void gen(Table table) throws Exception {
		genEntity(table);
		genSpringbootDao(table);
		genDao(table);
		genService(table);
		genController(table);
		genMybatis(table);
	}


	static {
		cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
		cfg.setDefaultEncoding("UTF-8");
		String filePath = GenKit.class.getClassLoader().getResource("template").getPath();
		File templateFile = new File(filePath);
		try {
			cfg.setDirectoryForTemplateLoading(templateFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	/**
	 * 获取所有表
	 */
	public static List<Table> genTable() {
		GenTables t = GenTables.me(DBUtils.basePackname);
		t.setRemovedTableNamePrefixes(DBUtils.removedTableNamePrefixes);
		t.setTableNames(DBUtils.tableNames);
		t.setMybatisPath(DBUtils.mybatisPath);
		List<Table> tables = t.getTables();
		return tables;
	}

	/**
	 * 自动生成代码
	 *
	 * @throws TemplateException
	 * @throws IOException
	 */
	public static void autoGen() throws Exception {

		List<Table> tables = genTable();
		for (Table table : tables) {
			gen(table);
		}
	}

	/**
	 * 生成实体类文件
	 */
	public static void genEntity(Table table) throws Exception {
		String entityPath = DBUtils.srcPath + table.getEntityPackageName().replace(".", File.separator)
				+ File.separatorChar;
		File entityFile = new File(entityPath);
		if (!entityFile.exists()) {
			entityFile.mkdirs();
		}
		entityPath += table.getClassName() + ".java";
		Map<String, Object> entityMap = new HashMap<String, Object>();
		entityMap.put("model", table);
		Writer entityOut = new OutputStreamWriter(new FileOutputStream(entityPath), "UTF-8");
		Template entityTemplate = cfg.getTemplate("Entity.java.ftl", "UTF-8");
		entityTemplate.process(entityMap, entityOut);
	}


	/**
	 * 生成dao文件
	 */
	public static void genDao(Table table) throws Exception {
		String daoPath =  DBUtils.srcPath + table.getDaoPackageName().replace(".", File.separator)
				+ File.separatorChar;
		File daoFile = new File(daoPath);
		if (!daoFile.exists()) {
			daoFile.mkdirs();
		}
		daoPath += table.getClassName() + "Dao.java";
		Map<String, Object> daoMap = new HashMap<String, Object>();
		daoMap.put("model", table);
		Writer daoOut = new OutputStreamWriter(new FileOutputStream(daoPath), "UTF-8");
		Template daoTemplate = cfg.getTemplate("Dao.java.ftl", "UTF-8");
		daoTemplate.process(daoMap, daoOut);
	}

	/**
	 * 生成springboot-dao文件
	 */
	public static void genSpringbootDao(Table table) throws Exception {
		String daoPath =  DBUtils.srcPath + table.getDaoPackageName().replace(".", File.separator)
				+ File.separatorChar;
		File daoFile = new File(daoPath);
		if (!daoFile.exists()) {
			daoFile.mkdirs();
		}
		daoPath += table.getClassName() + "Dao.java";
		Map<String, Object> daoMap = new HashMap<String, Object>();
		daoMap.put("model", table);
		Writer daoOut = new OutputStreamWriter(new FileOutputStream(daoPath), "UTF-8");
		Template daoTemplate = cfg.getTemplate("springboot-Dao.java.ftl", "UTF-8");
		daoTemplate.process(daoMap, daoOut);
	}

	/**
	 * 生成service文件
	 */
	public static void genService(Table table) throws Exception {
		String servicePath =  DBUtils.srcPath + table.getServicePackageName().replace(".", File.separator)
				+ File.separatorChar;
		File serviceFile = new File(servicePath);
		if (!serviceFile.exists()) {
			serviceFile.mkdirs();
		}
		servicePath += table.getClassName() + "Service.java";
		Map<String, Object> serviceMap = new HashMap<String, Object>();
		serviceMap.put("model", table);
		Writer serviceOut = new OutputStreamWriter(new FileOutputStream(servicePath), "UTF-8");
		Template serviceTemplate = cfg.getTemplate("Service.java.ftl", "UTF-8");
		serviceTemplate.process(serviceMap, serviceOut);
	}

	/**
	 * 生成controller文件
	 */
	public static void genController(Table table) throws Exception {
		String controllerPath = DBUtils.srcPath + table.getControllerPackageName().replace(".", File.separator)
				+ File.separatorChar;
		File controllerFile = new File(controllerPath);
		if (!controllerFile.exists()) {
			controllerFile.mkdirs();
		}
		controllerPath += table.getClassName() + "Controller.java";
		Map<String, Object> controllerMap = new HashMap<String, Object>();
		controllerMap.put("model", table);
		Writer controllerOut = new OutputStreamWriter(new FileOutputStream(controllerPath), "UTF-8");
		Template controllerTemplate = cfg.getTemplate("Controller.java.ftl", "UTF-8");
		controllerTemplate.process(controllerMap, controllerOut);
	}

	/**
	 * 生成mybatis文件
	 */
	public static void genMybatis(Table table) throws Exception {
		String mybatisPath =  DBUtils.srcPath + table.getMybatisPath().replace(".", File.separator)
				+ File.separatorChar;
		File mybatisFile = new File(mybatisPath);
		if (!mybatisFile.exists()) {
			mybatisFile.mkdirs();
		}
		mybatisPath += table.getClassName() + ".xml";
		Map<String, Object> mybatisMap = new HashMap<String, Object>();
		mybatisMap.put("model", table);
		Writer mybatisOut = new OutputStreamWriter(new FileOutputStream(mybatisPath), "UTF-8");
		Template mybatisTemplate = cfg.getTemplate("Mapper.xml.ftl", "UTF-8");
		mybatisTemplate.process(mybatisMap, mybatisOut);
	}

}
